Ordinary
About

만들면서 배우는 클린 아키텍처 (10 ~ 11)

profileordilov / 2022. 3. 3

아키텍처 경계 강제하기

경계와 의존성

아키텍처에서 경계를 구분하려면 어떤 요소들이 경계에 있을지 구분해야 합니다. 가장 안쪽에는 도메인 엔티티, 애플리케이션 계층 서비스 안에 유즈케이스가 위치합니다. 어댑터는 인커밍 포트로 서비스에 접근하고, 서비스는 아웃고잉 포트로 어댑터에 접근합니다.

접근 제한자

경꼐를 강제하기 위한 가장 기본적인 도구는 접근 제한자입니다. package-private 제한자를 이용하면 클래스들을 응집적인 모듈로 만들어줍니다. 패키지 바깥에서는 접근할 수 없으므로 모듈의 진입점만 public으로 만들면 됩니다.

컴파일 후 체크

클래스에 public 제한자를 쓰면 의존성 방향이 잘못되어도 컴파일러는 허용합니다. 적용할 수 있는 다른 방법은 컴파일 후 체크를 도입합니다. 캄파일된 후에 런타임에 체크해서 자동화된 테스트 과정에서 가장 잘 동작합니다. 이러한 체크를 도와주는 자바용 도구는 ArchUnit이 있습니다. 단위 테스트 프레임워크에서 의존성 규칙을 위반하면 테스트를 실패시킵니다.

의식적으로 지름길 사용하기

깨끗한 상태로 시작할 책임

한 번 지름길을 쓰기 시작하면 계속해서 사용하게 됩니다.

유스케이스 간 모델 공유하기

모델에서 특정 세부사항을 변경할 경우 두 유스케이스 모두에 영향이 갑니다. 만약 두 유스케이스가 독립적으로 진화해야 한다면 분리해서 시작해야 합니다.

도메인 엔티티를 입출력 모델로 사용하기

엔티티에 존재하지 않는 정보를 유스케이스가 필요로 한다면 엔티티가 아닌 다른 곳에 저장되야 합니다. 하지만 유스케이스 인터페이스에서 사용할 수 있어 엔티티에 필드를 추가하고 싶다고 생각이 듭니다. 서비스가 커질수록 단순한 도메인에서 복잡한 입출력이 필요해지므로 변경이 필요합니다.

인커밍 포트 건너뛰기

인커밍 포트는 애플리케이션 중심에 접근하는 진입점입니다. 바로 애플리케이션에 접근하면 어떤 서비스 메서드를 호출할지 내부를 파악해야 합니다. 또 인커밍 포트가 있어야 아키텍처를 강제할 수 있습니다.

애플리케이션 서비스 건너뛰기

영속성 어댑터가 인커밍 포트를 대체하는 방법입니다. 단순한 CRUD 유스케이스에서는 어댑터에 전달하고 받는게 전부이기 때문에 대신할 수 있습니다. 하지만 이 방법은 인커밍과 아웃고잉 어댑터 사이에 모델을 공유해야 합니다. 또 애플리케이션 코어에 유스케이스라고 할만한 게 없습니다. 나중에 CRUD에서 복잡해지면 아웃잉 어댑터를 추가하고 싶어집니다. 문제는 이렇게 되면 도메인 로직이 흩어져서 도메인 로직을 찾거나 유지보수하기 어렵습니다.

지름길을 택하더라도 중요한 것은 왜 선택했는지 기록을 남겨야 합니다. 기록을 남겨서 나중에 작업할 사람들이 이 결정에 대해 다시 평가할 수 있어야 합니다.